package com.coffee.admin.service.merchant.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;

import com.alibaba.fastjson.JSONObject;
import com.coffee.admin.api.common.query.GtRegionQuery;
import com.coffee.admin.api.common.service.RedisService;
import com.coffee.admin.api.common.service.SmsCodeService;
import com.coffee.admin.api.login.request.ForgetByPasswordReq;
import com.coffee.admin.api.login.request.ForgetBySmsReq;
import com.coffee.admin.api.login.request.LoginByPasswordRequert;
import com.coffee.admin.api.login.request.LoginBySmsRequert;
import com.coffee.admin.api.merchant.query.MerchantQuery;
import com.coffee.admin.api.merchant.rep.MerchantCityRep;
import com.coffee.admin.api.merchant.rep.MerchantDetailRep;
import com.coffee.admin.api.merchant.rep.MerchantListRep;
import com.coffee.admin.api.merchant.req.*;
import com.coffee.admin.api.merchant.result.IntegralResult;
import com.coffee.admin.api.merchant.result.MerchantResult;
import com.coffee.admin.api.merchant.service.MerchantService;
import com.coffee.admin.api.platform.query.PlatformSystemDeployQuery;
import com.coffee.admin.api.supplier.query.SupplierQuery;
import com.coffee.admin.service.common.bean.GtRegion;
import com.coffee.admin.service.common.dao.GtRegionDao;
import com.coffee.admin.service.merchant.bean.Merchant;
import com.coffee.admin.service.merchant.bean.MerchantCity;
import com.coffee.admin.service.merchant.bean.MerchantIntegralLog;
import com.coffee.admin.service.merchant.dao.MerchantCityDao;
import com.coffee.admin.service.merchant.dao.MerchantDao;
import com.coffee.admin.service.merchant.dao.MerchantIntegralLogDao;
import com.coffee.admin.service.platform.bean.Platform;
import com.coffee.admin.service.platform.bean.PlatformSystemDeploy;
import com.coffee.admin.service.platform.dao.PlatformDao;
import com.coffee.admin.service.platform.dao.PlatformSystemDeployDao;
import com.coffee.admin.service.supplier.bean.Supplier;
import com.coffee.admin.service.supplier.dao.SupplierDao;
import com.coffee.core.constant.Status;
import com.coffee.core.entity.LoginUser;
import com.coffee.core.entity.Page;
import com.coffee.core.entity.PagerInfo;
import com.coffee.core.enums.*;
import com.coffee.core.exception.BusinessException;
import com.coffee.core.exception.ValidateBusinessException;
import com.coffee.core.result.Result;
import com.coffee.core.util.*;
import com.coffee.daili.api.query.DailiMerchantQuery;
import com.coffee.daili.service.bean.DailiMerchant;
import com.coffee.daili.service.dao.DailiMerchantDao;
import com.coffee.order.api.inquire.result.WeiXinPushIntegralResult;
import com.coffee.order.api.sku.query.OrderBalanceQuery;
import com.coffee.order.service.sku.bean.OrderBalance;
import com.coffee.order.service.sku.dao.OrderBalanceDao;
import com.coffee.order.service.sku.dao.SkuOrderDao;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;


@DubboService(dynamic = true)
public class MerchantServiceImpl implements MerchantService {
    private static final Logger logger = LoggerFactory.getLogger(MerchantServiceImpl.class);
    @Resource
    private MerchantDao merchantDao;
    @Resource
    private SupplierDao supplierDao;
    @Resource
    private PlatformDao platformDao;
    @Resource
    private PlatformSystemDeployDao platformSystemDeployDao;
    @Resource
    private MerchantCityDao merchantCityDao;
    @Resource
    private MerchantIntegralLogDao merchantIntegralLogDao;
    @Resource
    private DailiMerchantDao dailiMerchantDao;
    @Resource
    private SkuOrderDao skuOrderDao;
    @Resource
    private GtRegionDao gtRegionDao;
    @Resource
    private OrderBalanceDao orderBalanceDao;
    @DubboReference
    private SmsCodeService smsCodeService;
    @DubboReference
    private RedisService redisService;

    @Override
    public Page<MerchantListRep> getPager(MerchantListReq req, PagerInfo pr) {
        MerchantQuery merchantQuery = new MerchantQuery();
        BeanUtilExt.copyProperties(merchantQuery, req);
        Page<MerchantListRep> pager = new Page<MerchantListRep>(pr.getStart(), pr.getPageSize());
        Integer count = merchantDao.count(merchantQuery);
        pager.setTotalPage(count);
        if (count > 0) {
            List<Merchant> list = merchantDao.page(merchantQuery, pr.getStart(), pr.getPageSize());
            List<MerchantListRep> merchantListReps = DTOUtils.convertList(list, MerchantListRep.class);
            for (MerchantListRep merchantListRep : merchantListReps) {
                OrderBalanceQuery orderBalanceQuery = new OrderBalanceQuery();
                orderBalanceQuery.setMerchantId(merchantListRep.getId());
                orderBalanceQuery.setStatus("success");
                orderBalanceQuery.setRechargeType("recharge");
                Double aDouble = orderBalanceDao.sumRechargeMoney(orderBalanceQuery);
                merchantListRep.setRechargeBalance(aDouble);
            }
            pager.setData(merchantListReps);
        }
        return pager;
    }

    @Override
    public Page<MerchantListRep> getSupplierAndMerchantPager(MerchantListReq req, PagerInfo pr) {
        MerchantQuery merchantQuery = new MerchantQuery();
        BeanUtilExt.copyProperties(merchantQuery, req);
        Page<MerchantListRep> pager = new Page<MerchantListRep>(pr.getStart(), pr.getPageSize());
        Integer count = merchantDao.getSupplierMerchantCount(merchantQuery);
        pager.setTotalPage(count);
        if (count > 0) {
            List<Merchant> list = merchantDao.getSupplierMerchantPage(merchantQuery, pr.getStart(), pr.getPageSize());
            List<MerchantListRep> listReps = DTOUtils.convertList(list, MerchantListRep.class);
            for (MerchantListRep listRep : listReps) {
                SupplierQuery param = new SupplierQuery();
                param.setMobile(listRep.getMobile());
                Supplier supplier = supplierDao.findFirst(param);
                if (supplier != null) {
                    listRep.setName(supplier.getName());
                    listRep.setIsEnable(supplier.getIsEnable());
                    continue;
                }
                MerchantQuery merchantQuery1 = new MerchantQuery();
                merchantQuery1.setMobile(listRep.getMobile());
                Merchant merchant = merchantDao.findFirst(merchantQuery1);
                if (merchant != null) {
                    listRep.setName(merchant.getName());
                    listRep.setIsEnable(merchant.getIsEnable());
                }
            }
            pager.setData(listReps);
        }
        return pager;
    }

    @Override
    public Integer count(MerchantQuery param) {
        Integer count = merchantDao.count(param);
        return count;
    }

    @Override
    public MerchantResult getDetail(Integer id) {
        Merchant item = merchantDao.findById(id);
        if (item == null) {
            return null;
        }
        MerchantResult result = new MerchantResult();
        BeanUtilExt.copyProperties(result, item);
        result.setIsHaveBalance(result.getBalance() != null && result.getBalance() != 0.0);
        DailiMerchantQuery param = new DailiMerchantQuery();
        param.setMobile(result.getMobile());
        DailiMerchant dailiMerchant = dailiMerchantDao.findFirst(param);
        if (dailiMerchant != null) {
            result.setDailiRole(dailiMerchant.getRole());
            result.setDailiStatus(dailiMerchant.getStatus());
            result.setDailiMerchantId(dailiMerchant.getId());
            result.setPeopleNumber(dailiMerchant.getPeopleNumber());
            result.setDailiExplain(dailiMerchant.getExplain());
            result.setDailiReason(dailiMerchant.getReason());
            result.setDailiIsEnable(dailiMerchant.getIsEnable());
            if (dailiMerchant.getQuota() != null && dailiMerchant.getQuota() > 0
                    && DailiMerchantRoleEnum.MERCHANT.getCode().equals(dailiMerchant.getRole())) {
                Double enjoyPayPrice = skuOrderDao.getEnjoyPayPrice(result.getId(), null, null);
                result.setSurplusQuota(new BigDecimal(dailiMerchant.getQuota() + "").subtract(new BigDecimal(enjoyPayPrice + "")).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
                result.setQuota(new BigDecimal(dailiMerchant.getQuota() + "").setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
            } else if (dailiMerchant.getQuota() != null && dailiMerchant.getQuota() > 0
                    && DailiMerchantRoleEnum.PARTNER.getCode().equals(dailiMerchant.getRole())) {
                Double quota = dailiMerchantDao.findQuotaByPid(dailiMerchant.getPidPath());
                result.setQuota(new BigDecimal(dailiMerchant.getQuota() + "").setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
                result.setSurplusQuota(new BigDecimal(result.getQuota() + "").subtract(new BigDecimal(quota + "")).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
            }
        }
        return result;
    }

    @Override
    public IntegralResult getIntegralResult(Integer id) {
        IntegralResult integralResult = new IntegralResult();
        Merchant merchant = merchantDao.findById(id);
        if (merchant == null) {
            return null;
        }
        PlatformSystemDeployQuery platformSystemDeployQuery = new PlatformSystemDeployQuery();
        platformSystemDeployQuery.setType(SkuTypeEnum.INTEGRAL.getCode());
        platformSystemDeployQuery.setStatus(IntegralOperationEnum.DEDUCTION.getCode());
        PlatformSystemDeploy platformSystemDeploy = platformSystemDeployDao.findFirst(platformSystemDeployQuery);
        if (platformSystemDeploy == null) {
            return null;
        }
        integralResult.setIntegral(merchant.getIntegral());
        integralResult.setDetails(platformSystemDeploy.getDetails());
        integralResult.setUnit(platformSystemDeploy.getUnit());
        return integralResult;
    }

    @Override
    public MerchantResult getDetailByOpenId(String openId) {
        Merchant merchant = merchantDao.findByOpenId(openId);
        if (merchant == null) {
            return null;
        }
        MerchantResult result = new MerchantResult();
        BeanUtilExt.copyProperties(result, merchant);
        return result;
    }

    @Override
    public MerchantResult getDetailByMobile(String mobile) throws BusinessException {
        MerchantQuery param = new MerchantQuery();
        param.setMobile(mobile);
        param.setIsEnable("Y");
        Merchant merchant = merchantDao.findFirst(param);
        ValidateBusinessException.assertNonNull(merchant, ExceptionEnum.ERROR_1402);
        MerchantResult result = new MerchantResult();
        BeanUtilExt.copyProperties(result, merchant);
        return result;
    }

    @Override
    public MerchantDetailRep platformGetDetail(Integer id) {
        Merchant item = merchantDao.findById(id);
        if (item == null) {
            return null;
        }
        MerchantDetailRep result = new MerchantDetailRep();
        BeanUtilExt.copyProperties(result, item);
        List<MerchantCity> merchantCities = merchantCityDao.findByMerchantId(id);
        List<MerchantCityRep> merchantCityReps = DTOUtils.convertList(merchantCities, MerchantCityRep.class);
        for (MerchantCityRep merchantCityRep : merchantCityReps) {
            MerchantCity merchantCity = getMerchantCity(merchantCityRep.getId());
            merchantCityRep.setAddress(merchantCity.getProvinceName() + merchantCity.getCityName() + merchantCity.getAreaName() + merchantCity.getAddress());
        }
        result.setMerchantCityRepList(merchantCityReps);
        return result;
    }

    MerchantCity getMerchantCity(Integer merchantCityId) {
        MerchantCity merchantCity = merchantCityDao.findById(merchantCityId);
        if (merchantCity != null) {
            if (merchantCity.getProvinceId() != null) {
                GtRegion province = gtRegionDao.findById(merchantCity.getProvinceId());
                if (province != null)
                    merchantCity.setProvinceName(province.getName());
            }
            if (merchantCity.getCityId() != null) {
                GtRegion city = gtRegionDao.findById(merchantCity.getCityId());
                if (city != null)
                    merchantCity.setCityName(city.getName());
            }
            if (merchantCity.getAreaId() != null) {
                GtRegion area = gtRegionDao.findById(merchantCity.getAreaId());
                if (area != null)
                    merchantCity.setAreaName(area.getName());
            }
            return merchantCity;
        } else {
            return null;
        }
    }

    @Override
    public List<MerchantResult> getList(MerchantQuery param, PagerInfo pr) {
        List<Merchant> list = merchantDao.page(param, pr.getStart(), pr.getPageSize());
        return DTOUtils.convertList(list, MerchantResult.class);
    }

    @Override
    public List<MerchantResult> getList(MerchantQuery param) {
        List<Merchant> list = merchantDao.page(param, 0, Integer.MAX_VALUE);
        return DTOUtils.convertList(list, MerchantResult.class);
    }

    @Override
    public List<MerchantResult> getList() {
        MerchantQuery param = new MerchantQuery();
        List<Merchant> list = merchantDao.page(param, 0, Integer.MAX_VALUE);
        return DTOUtils.convertList(list, MerchantResult.class);
    }


    @Override
    public void delete(Integer id) {
        merchantDao.deleteById(id);
    }

    @Override
    public void add(MerchantResult result) throws BusinessException {
        Merchant item = new Merchant();
        BeanUtilExt.copyProperties(item, result);
        item.setUuid(UUIDUtils.getUUID());
        item.setCreateTime(new Date());
        item.setPassword(PasswordUtil.getPass(result.getPassword()));
        if (StringUtils.isNotEmpty(result.getProvince())) {
            GtRegionQuery gtRegionQuery = new GtRegionQuery();
            gtRegionQuery.setName(result.getProvince());
            GtRegion gtRegion = gtRegionDao.findFirst(gtRegionQuery);
            if (gtRegion != null) {
                item.setCode(gtRegion.getCode());
            }
        }
        item.setBalance(0.0);
        merchantDao.insert(item);
        MerchantCity merchantCity = new MerchantCity();
        merchantCity.setMerchantId(item.getId());
        merchantCity.setAddress(result.getAddress());
        merchantCity.setIsDefault("Y");
        merchantCity.setCreateTime(new Date());
        merchantCity.setReceiver(result.getShopName());
        merchantCityDao.insert(merchantCity);
    }


    @Override
    public void update(MerchantResult result) throws BusinessException {
        Merchant item = new Merchant();
        BeanUtilExt.copyProperties(item, result);
        Merchant tmp = merchantDao.findById(item.getId());
        if (tmp == null) {
            throw new BusinessException(ExceptionEnum.ERROR_0002.getCode(), ExceptionEnum.ERROR_0002.getMessage());
        }
        merchantDao.updateById(item);

    }

    @Override
    public void updateMobile(MerchantUpdateMobileReq req) throws BusinessException {
        MerchantQuery param = new MerchantQuery();
        param.setMobile(req.getMobile());
        Merchant merchant = merchantDao.findFirst(param);
        if (merchant != null) {
            throw new BusinessException(ExceptionEnum.ERROR_1400.getCode(), ExceptionEnum.ERROR_1400.getMessage());
        }
        if (StringUtils.isNoneBlank(req.getSmsCode())) {
            boolean isValid = smsCodeService.validateSmsCode(req.getMobile(), req.getSmsCode(), SmsSourceEnum.CHANGE_MOBILE);
            if (!isValid) {
                throw BusinessException.build(ExceptionEnum.ERROR_1210);
            }
        }
        Merchant item = new Merchant();
        BeanUtilExt.copyProperties(item, req);
        merchantDao.updateById(item);
    }

    @Override
    public void updatePassword(MerchantUpdatePasswordReq req) throws BusinessException {
        Merchant merchant = merchantDao.findById(req.getId());
        if (merchant == null) {
            throw BusinessException.build(ExceptionEnum.ERROR_1402);
        }
        if (PasswordUtil.checkPass(merchant.getPassword(), req.getNewPassword())) {
            throw BusinessException.build(ExceptionEnum.ERROR_1401);
        }
        Merchant item = new Merchant();
        item.setId(req.getId());
        item.setPassword(PasswordUtil.getPass(req.getNewPassword()));
        merchantDao.updateById(item);
    }


    @Override
    public void updateBuyPermission(MerchantUpdateBuyPermissionReq req) throws BusinessException {
        Merchant item = new Merchant();
        item.setId(req.getId());
        item.setBuyPermission(req.getBuyPermission());
        merchantDao.updateById(item);
    }

    @Override
    public void updateIsEnable(MerchantUpdateIsEnableReq req) throws BusinessException {
        Merchant item = new Merchant();
        item.setId(req.getId());
        item.setIsEnable(req.getIsEnable());
        merchantDao.updateById(item);
    }

    @Override
    @Transactional
    public WeiXinPushIntegralResult updateIntegral(MerchantUpdateIntegralReq req) throws BusinessException {
        WeiXinPushIntegralResult weiXinPushIntegralResult = new WeiXinPushIntegralResult();
        Platform platform = platformDao.findById(req.getOperationId());
        if (platform == null) {
            throw BusinessException.build(ExceptionEnum.ERROR_1306);
        }
        Merchant merchant = merchantDao.findById(req.getId());
        if (merchant == null) {
            throw BusinessException.build(ExceptionEnum.ERROR_1402);
        }
        MerchantIntegralLog param = new MerchantIntegralLog();
        param.setMerchantId(req.getId());
        param.setOperation(req.getIntegralOperation());
        param.setBeforeIntegral(merchant.getIntegral());
        param.setPlatformId(req.getOperationId());
        param.setRemarks(req.getOperationName());
        param.setCreateTime(new Date());
        param.setRemarks(req.getRemarks());
        PlatformSystemDeploy platformSystemDeploy = jfPlatformSystemDeploy();
        if (IntegralOperationEnum.ADD.getCode().equals(req.getIntegralOperation())) {
            merchantDao.addIntegral(req.getId(), req.getIntegral());
            param.setOperation(IntegralOperationEnum.ADD.getCode());
            weiXinPushIntegralResult.setIntegral(req.getIntegral());
            weiXinPushIntegralResult.setRemark(IntegralOperationEnum.ADD.getName());
            Double integerPrice = new BigDecimal(merchant.getIntegral()).add(new BigDecimal(req.getIntegral())).divide(new BigDecimal(platformSystemDeploy.getUnit()), 2, BigDecimal.ROUND_HALF_EVEN)
                    .multiply(new BigDecimal(platformSystemDeploy.getDetails())).setScale(2, RoundingMode.HALF_EVEN).doubleValue();
            weiXinPushIntegralResult.setIntegralPrice(integerPrice);
        } else if (IntegralOperationEnum.DELETE.getCode().equals(req.getIntegralOperation())) {
            Integer integer = merchantDao.deleteIntegral(req.getId(), req.getIntegral());
            if (integer <= 0) {
                throw BusinessException.build(ExceptionEnum.ERROR_1403);
            }
            param.setOperation(IntegralOperationEnum.DELETE.getCode());
            weiXinPushIntegralResult.setIntegral(req.getIntegral());
            weiXinPushIntegralResult.setRemark(IntegralOperationEnum.DELETE.getName());
            Double integerPrice = new BigDecimal(merchant.getIntegral()).subtract(new BigDecimal(req.getIntegral())).divide(new BigDecimal(platformSystemDeploy.getUnit()), 2, BigDecimal.ROUND_HALF_EVEN)
                    .multiply(new BigDecimal(platformSystemDeploy.getDetails())).setScale(2, RoundingMode.HALF_EVEN).doubleValue();
            weiXinPushIntegralResult.setIntegralPrice(integerPrice);
        } else {
            throw BusinessException.build(ExceptionEnum.ERROR_1403);
        }
        Merchant newMerchant = merchantDao.findById(req.getId());
        param.setAfterIntegral(newMerchant.getIntegral());
        merchantIntegralLogDao.insert(param);
        weiXinPushIntegralResult.setOpenId(merchant.getGzhOpenId());
        weiXinPushIntegralResult.setCreateTime(new Date());
        weiXinPushIntegralResult.setMerchantName(merchant.getName());
        return weiXinPushIntegralResult;
    }

    public PlatformSystemDeploy jfPlatformSystemDeploy() throws BusinessException {
        PlatformSystemDeployQuery platformSystemDeployQuery = new PlatformSystemDeployQuery();
        platformSystemDeployQuery.setType(SkuTypeEnum.INTEGRAL.getCode());
        platformSystemDeployQuery.setStatus(IntegralOperationEnum.DEDUCTION.getCode());
        PlatformSystemDeploy platformSystemDeploy = platformSystemDeployDao.findFirst(platformSystemDeployQuery);
        ValidateBusinessException.assertNonNull(platformSystemDeploy, ExceptionEnum.ERROR_1704);
        return platformSystemDeploy;
    }

    @Override
    public Map<Integer, MerchantResult> getItemMap(Set<Integer> idSet) {
        Map<Integer, MerchantResult> map = new HashMap<Integer, MerchantResult>();
        List<Merchant> list = merchantDao.findByIds(StringUtil.setToList(idSet));
        List<MerchantResult> resultList = DTOUtils.convertList(list, MerchantResult.class);
        for (MerchantResult item : resultList) {
            map.put(item.getId(), item);
        }
        return map;
    }

    @Override
    public Map<Integer, MerchantResult> getItemMap() {
        Map<Integer, MerchantResult> map = new HashMap<Integer, MerchantResult>();
        MerchantQuery param = new MerchantQuery();
        List<Merchant> list = merchantDao.page(param, 0, Integer.MAX_VALUE);
        List<MerchantResult> resultList = DTOUtils.convertList(list, MerchantResult.class);
        for (MerchantResult item : resultList) {
            map.put(item.getId(), item);
        }
        return map;
    }

    /***
     * @Description: 校验手机号码
     */
    public void checkMobile(String mobile) throws BusinessException {
        ValidateBusinessException.assertStringNotBlank(mobile, ExceptionEnum.ERROR_1201);
        boolean isMobile = RegexUtils.checkMobile(mobile);
        ValidateBusinessException.assertTrue(isMobile, ExceptionEnum.ERROR_1218);
    }

    @Override
    public String register(RegisterReq req) throws BusinessException {
        logger.info("=========用户注册参数===========req：" + JSONObject.toJSONString(req));
        //校验手机号
        String mobile = req.getMobile();
        this.checkMobile(mobile);

        //校验密码
        String password = req.getPassword();
        ValidateBusinessException.assertStringNotBlank(password, ExceptionEnum.ERROR_1202);

        //校验验证码
        String smsCode = req.getSmsCode();
        boolean isValid = smsCodeService.validateSmsCode(mobile, smsCode, SmsSourceEnum.USER_REGISTER);
        if (!isValid) {
            throw BusinessException.build(ExceptionEnum.ERROR_1210);
        }
        //创建用户
        MerchantQuery merchantQuery = new MerchantQuery();
        merchantQuery.setMobile(req.getMobile());
        //判断该成员是否已经注册
        Merchant user = merchantDao.findFirst(merchantQuery);
        ValidateBusinessException.assertNull(user, ExceptionEnum.ERROR_1234);
        String uuid = UUIDUtils.getUUID();
        user = new Merchant();
        user.setName(StringUtil.mobileNick(mobile));
        user.setMobile(req.getMobile());
        user.setPassword(req.getPassword());
        user.setIdNumber("");
        user.setBuyPermission(SkuTypeEnum.SKU.getCode());
        user.setIntegral(0);
        user.setPid(0);
        user.setUuid(uuid);
        user.setCreateTime(new Date());
        user.setIsEnable("Y");
        user.setCity(req.getCity());
        user.setProvince(req.getProvince());
        if (StringUtils.isNotEmpty(req.getProvince())) {
            GtRegionQuery gtRegionQuery = new GtRegionQuery();
            gtRegionQuery.setName(req.getProvince());
            GtRegion gtRegion = gtRegionDao.findFirst(gtRegionQuery);
            if (gtRegion != null) {
                user.setCode(gtRegion.getCode());
            }
        }
        user.setBalance(0.0);
        merchantDao.insert(user);

        // 保存用户信息到redis中
        String token = "c-" + uuid;
        LoginUser userBo = new LoginUser();
        userBo.setUserId(user.getId());
        redisService.set(token, JSONObject.toJSONString(userBo), Status.ExpireEnum.UNREAD_MSG);
        logger.info("============用户注册成功============token" + token);
        //
        out:
        if (req.getDailiMerchantId() != null) {
            DailiMerchant dailiMerchant = dailiMerchantDao.findById(req.getDailiMerchantId());
            DailiMerchantQuery query = new DailiMerchantQuery();
            query.setMobile(mobile);
            DailiMerchant dailiMerchantDaoFirst = dailiMerchantDao.findFirst(query);
            if (dailiMerchant != null && dailiMerchantDaoFirst == null) {
                DailiMerchant param = new DailiMerchant();
                param.setMobile(mobile);
                if ("fenxiao".equals(req.getRole())) {
                    DailiMerchantQuery dailiMerchantQuery = new DailiMerchantQuery();
                    dailiMerchantQuery.setRole(DailiMerchantRoleEnum.DISTRIBUTOR.getCode());
                    dailiMerchantQuery.setPid(req.getDailiMerchantId());
                    dailiMerchantQuery.setIsEnable("Y");
                    Integer count = dailiMerchantDao.count(dailiMerchantQuery);
                    if (count >= dailiMerchant.getPeopleNumber()) {
                        break out;
                    }
                    param.setRole(DailiMerchantRoleEnum.DISTRIBUTOR.getCode());
                    param.setProportion(0.0);
                } else {
                    param.setRole(req.getRole());
                }
                param.setPid(req.getDailiMerchantId());
                param.setIsEnable("Y");
                param.setCreateTime(new Date());
                param.setStatus(DailiMerchantStatusEnum.SUCCESS.getCode());
                dailiMerchantDao.insert(param);
                DailiMerchant update = new DailiMerchant();
                update.setId(param.getId());
                update.setPidPath(dailiMerchant.getPidPath() + param.getId() + ",");
                dailiMerchantDao.updateById(update);
            }
        }


        return token;
    }

    @Override
    public String getByMobile(String mobile, String code) throws BusinessException {
        MerchantQuery query = new MerchantQuery();
        query.setMobile(mobile);
        Merchant merchant = merchantDao.findFirst(query);
        if (merchant == null && !(code.equals(SmsSourceEnum.USER_REGISTER.getCode()) || code.equals(SmsSourceEnum.BACKSTAGE_FORGOTPASSWORD.getCode()))) {
            throw BusinessException.build(ExceptionEnum.ERROR_1233);
        }
        return mobile;
    }


    @Override
    public String weixingRegister(RegisterReq req) throws BusinessException {
        logger.info("=========用户注册参数===========req：" + JSONObject.toJSONString(req));
        //校验手机号
        String mobile = req.getMobile();
        this.checkMobile(mobile);
        //创建用户
        MerchantQuery merchantQuery = new MerchantQuery();
        merchantQuery.setMobile(req.getMobile());
        //判断该成员是否已经注册
        Merchant user = merchantDao.findFirst(merchantQuery);
        if (user == null) {
            String uuid = UUIDUtils.getUUID();
            user = new Merchant();
            user.setHeadPortrait(req.getHeadPortrait());
            user.setName(StringUtil.mobileNick(mobile));
            user.setNickname(req.getNickname());
            user.setMobile(req.getMobile());
            user.setPassword(PasswordUtil.getPass("123456"));
            user.setIdNumber("");
            user.setBuyPermission(SkuTypeEnum.SKU.getCode());
            user.setIntegral(0);
            user.setPid(0);
            user.setUuid(uuid);
            user.setCreateTime(new Date());
            user.setIsEnable("Y");
            user.setOpenId(req.getOpenId());
            user.setCity(req.getCity());
            user.setProvince(req.getProvince());
            if (StringUtils.isNotEmpty(req.getProvince())) {
                GtRegionQuery gtRegionQuery = new GtRegionQuery();
                gtRegionQuery.setName(req.getProvince());
                GtRegion gtRegion = gtRegionDao.findFirst(gtRegionQuery);
                if (gtRegion != null) {
                    user.setCode(gtRegion.getCode());
                }
            }
            user.setBalance(0.0);
            merchantDao.insert(user);
        }
        if (!"Y".equals(user.getIsEnable())) {
            throw BusinessException.build(ExceptionEnum.ERROR_1228);
        }
        Merchant param = new Merchant();
        if (StringUtils.isBlank(user.getOpenId()) && StringUtils.isNotBlank(req.getOpenId())) {
            param.setOpenId(req.getOpenId());
        }
        if (StringUtils.isNotBlank(req.getNickname()) || StringUtils.isNotBlank(req.getHeadPortrait())) {
            param.setId(user.getId());
            param.setHeadPortrait(req.getHeadPortrait());
            param.setNickname(req.getNickname());
            merchantDao.updateById(param);
        }
        // 保存用户信息到redis中
        String token = "c-" + user.getUuid();
        LoginUser userBo = new LoginUser();
        userBo.setUserId(user.getId());
        redisService.set(token, JSONObject.toJSONString(userBo), Status.ExpireEnum.UNREAD_MSG);
        logger.info("============用户注册成功============token" + token);
        //添加分销
        if (req.getDailiMerchantId() != null) {
            DailiMerchant dailiMerchant = dailiMerchantDao.findById(req.getDailiMerchantId());
            DailiMerchantQuery query = new DailiMerchantQuery();
            query.setMobile(mobile);
            DailiMerchant dailiMerchantDaoFirst = dailiMerchantDao.findFirst(query);
            out:
            if (dailiMerchant != null && dailiMerchantDaoFirst == null) {
                DailiMerchant inset = new DailiMerchant();
                inset.setMobile(mobile);
                if ("fenxiao".equals(req.getRole())) {
                    DailiMerchantQuery dailiMerchantQuery = new DailiMerchantQuery();
                    dailiMerchantQuery.setRole(DailiMerchantRoleEnum.DISTRIBUTOR.getCode());
                    dailiMerchantQuery.setPid(req.getDailiMerchantId());
                    dailiMerchantQuery.setIsEnable("Y");
                    Integer count = dailiMerchantDao.count(dailiMerchantQuery);
                    if (count >= dailiMerchant.getPeopleNumber()) {
                        break out;
                    }
                    inset.setRole(DailiMerchantRoleEnum.DISTRIBUTOR.getCode());
                    inset.setProportion(0.0);
                } else {
                    inset.setRole(req.getRole());
                }
                inset.setPid(req.getDailiMerchantId());
                inset.setIsEnable("Y");
                inset.setCreateTime(new Date());
                inset.setStatus(DailiMerchantStatusEnum.SUCCESS.getCode());

                dailiMerchantDao.insert(inset);
                DailiMerchant update = new DailiMerchant();
                update.setId(inset.getId());
                update.setPidPath(dailiMerchant.getPidPath() + inset.getId() + ",");
                dailiMerchantDao.updateById(update);
            }
        }
        return token;
    }

    @Override
    public String passwordLogin(LoginByPasswordRequert req) throws BusinessException {
        logger.info("=========用户密码登录===========req：" + JSONObject.toJSONString(req));
        // 手机号码校验
        String mobile = req.getMobile();
        this.checkMobile(mobile);

        // 密码校验
        String password = req.getPassword();
        ValidateBusinessException.assertStringNotBlank(password, ExceptionEnum.ERROR_1202);


        MerchantQuery query = new MerchantQuery();
        query.setMobile(mobile);
        Merchant merchant = merchantDao.findFirst(query);
        if (merchant == null) {
            throw BusinessException.build(ExceptionEnum.ERROR_1233);
        }
        if (!PasswordUtil.checkPass(req.getPassword(), merchant.getPassword())) {
            throw BusinessException.build(ExceptionEnum.ERROR_1203);
        }
        if (!"Y".equals(merchant.getIsEnable())) {
            throw BusinessException.build(ExceptionEnum.ERROR_1228);
        }
        // 保存用户信息到redis中
        String token = "c-" + UUIDUtils.getUUID();
        LoginUser userBo = new LoginUser();
        userBo.setUserId(merchant.getId());
        userBo.setUserName(merchant.getName());
        redisService.set(token, JSONObject.toJSONString(userBo), Status.ExpireEnum.UNREAD_MSG);
        out:
        if (req.getDailiMerchantId() != null) {
            DailiMerchant dailiMerchant = dailiMerchantDao.findById(req.getDailiMerchantId());
            DailiMerchantQuery dailiMerchantQuery = new DailiMerchantQuery();
            dailiMerchantQuery.setMobile(mobile);
            DailiMerchant dailiMerchantDaoFirst = dailiMerchantDao.findFirst(dailiMerchantQuery);
            if (dailiMerchant != null && dailiMerchantDaoFirst == null) {
                DailiMerchant inset = new DailiMerchant();
                inset.setMobile(mobile);
                if ("fenxiao".equals(req.getRole())) {
                    DailiMerchantQuery pa = new DailiMerchantQuery();
                    pa.setRole(DailiMerchantRoleEnum.DISTRIBUTOR.getCode());
                    pa.setPid(req.getDailiMerchantId());
                    pa.setIsEnable("Y");
                    Integer count = dailiMerchantDao.count(pa);
                    if (count >= dailiMerchant.getPeopleNumber()) {
                        break out;
                    }
                    inset.setRole(DailiMerchantRoleEnum.DISTRIBUTOR.getCode());
                    inset.setProportion(0.0);
                } else {
                    inset.setRole(req.getRole());
                }
                inset.setPid(req.getDailiMerchantId());
                inset.setIsEnable("Y");
                inset.setCreateTime(new Date());
                inset.setStatus(DailiMerchantStatusEnum.SUCCESS.getCode());
                dailiMerchantDao.insert(inset);
                DailiMerchant update = new DailiMerchant();
                update.setId(inset.getId());
                update.setPidPath(dailiMerchant.getPidPath() + inset.getId() + ",");
                dailiMerchantDao.updateById(update);
            }
        }
        // 登录
        return token;
    }

    @Override
    public String smsLogin(LoginBySmsRequert req) throws BusinessException {
        // 手机号码校验
        String mobile = req.getMobile();
        this.checkMobile(mobile);

        MerchantQuery query = new MerchantQuery();
        query.setMobile(mobile);
        Merchant merchant = merchantDao.findFirst(query);
        if (merchant == null) {
            throw BusinessException.build(ExceptionEnum.ERROR_1233);
        }
        if (!"Y".equals(merchant.getIsEnable())) {
            throw BusinessException.build(ExceptionEnum.ERROR_1228);
        }
        // 校验验证码
        String smsCode = req.getSmsCode();
        boolean isValid = smsCodeService.validateSmsCode(mobile, smsCode, SmsSourceEnum.USER_LOGIN);
        if (!isValid) {
            throw BusinessException.build(ExceptionEnum.ERROR_1210);
        }
        // 登录
        String token = "c-" + UUIDUtils.getUUID();
        LoginUser userBo = new LoginUser();
        userBo.setUserId(merchant.getId());
        userBo.setUserName(merchant.getName());
        redisService.set(token, JSONObject.toJSONString(userBo), Status.ExpireEnum.UNREAD_MSG);
        out:
        if (req.getDailiMerchantId() != null) {
            DailiMerchant dailiMerchant = dailiMerchantDao.findById(req.getDailiMerchantId());
            DailiMerchantQuery dailiMerchantQuery = new DailiMerchantQuery();
            dailiMerchantQuery.setMobile(mobile);
            DailiMerchant dailiMerchantDaoFirst = dailiMerchantDao.findFirst(dailiMerchantQuery);
            if (dailiMerchant != null && dailiMerchantDaoFirst == null) {
                DailiMerchant inset = new DailiMerchant();
                inset.setMobile(mobile);
                if ("fenxiao".equals(req.getRole())) {
                    DailiMerchantQuery pa = new DailiMerchantQuery();
                    pa.setRole(DailiMerchantRoleEnum.DISTRIBUTOR.getCode());
                    pa.setPid(req.getDailiMerchantId());
                    pa.setIsEnable("Y");
                    Integer count = dailiMerchantDao.count(pa);
                    if (count >= dailiMerchant.getPeopleNumber()) {
                        break out;
                    }
                    inset.setRole(DailiMerchantRoleEnum.DISTRIBUTOR.getCode());
                    inset.setProportion(0.0);
                } else {
                    inset.setRole(req.getRole());
                }
                inset.setPid(req.getDailiMerchantId());
                inset.setIsEnable("Y");
                inset.setCreateTime(new Date());
                inset.setStatus(DailiMerchantStatusEnum.SUCCESS.getCode());
                dailiMerchantDao.insert(inset);
                DailiMerchant update = new DailiMerchant();
                update.setId(inset.getId());
                update.setPidPath(dailiMerchant.getPidPath() + inset.getId() + ",");
                dailiMerchantDao.updateById(update);
            }
        }
        return token;
    }

    @Override
    public String forgetBySmsReq(ForgetBySmsReq req) throws BusinessException {
        // 手机号码校验
        String mobile = req.getMobile();
        this.checkMobile(mobile);

        MerchantQuery query = new MerchantQuery();
        query.setMobile(mobile);
        Merchant merchant = merchantDao.findFirst(query);
        if (merchant == null) {
            throw BusinessException.build(ExceptionEnum.ERROR_1233);
        }
        if (!"Y".equals(merchant.getIsEnable())) {
            throw BusinessException.build(ExceptionEnum.ERROR_1228);
        }
        // 校验验证码
        String smsCode = req.getSmsCode();
        boolean isValid = smsCodeService.validateSmsCode(mobile, smsCode, SmsSourceEnum.CHANGE_PASSWORD);
        if (!isValid) {
            throw BusinessException.build(ExceptionEnum.ERROR_1210);
        }
        Merchant update = new Merchant();
        update.setId(merchant.getId());
        update.setPassword(req.getPassword());
        merchantDao.updateById(update);
        return "SUCCESS";
    }

    @Override
    public String forgetByPasswordReq(ForgetByPasswordReq req) throws BusinessException {
        // 手机号码校验
        String mobile = req.getMobile();
        this.checkMobile(mobile);

        MerchantQuery query = new MerchantQuery();
        query.setMobile(mobile);
        Merchant merchant = merchantDao.findFirst(query);
        if (merchant == null) {
            throw BusinessException.build(ExceptionEnum.ERROR_1233);
        }
        if (!"Y".equals(merchant.getIsEnable())) {
            throw BusinessException.build(ExceptionEnum.ERROR_1228);
        }
        // 校验验证码
        if (!PasswordUtil.checkPass(req.getOldPassword(), merchant.getPassword())) {
            throw BusinessException.build(ExceptionEnum.ERROR_1414);
        }
        if (PasswordUtil.checkPass(req.getNewPassword(), merchant.getPassword())) {
            throw BusinessException.build(ExceptionEnum.ERROR_1401);
        }
        Merchant update = new Merchant();
        update.setId(merchant.getId());
        update.setPassword(PasswordUtil.getPass(req.getNewPassword()));
        merchantDao.updateById(update);
        return "SUCCESS";
    }

    @Override
    public void updateMerchantCity() throws Exception {
        List<Merchant> list = merchantDao.list(new MerchantQuery());
        for (Merchant merchant : list) {
            logger.info("merchant====" + JSONObject.toJSONString(merchant));
            Merchant updateM = new Merchant();
            updateM.setId(merchant.getId());
            ToolMobileSegmentResult mobileSeg = ZhongtailClient.getMobileSeg(merchant.getMobile());
            updateM.setCity(mobileSeg.getCity());
            String province = mobileSeg.getProvince();
            updateM.setProvince(province);
            GtRegionQuery gtRegionQuery = new GtRegionQuery();
            gtRegionQuery.setName(province);
            GtRegion gtRegion = gtRegionDao.findFirst(gtRegionQuery);
            if (gtRegion != null) {
                updateM.setCode(gtRegion.getCode());
            }
            logger.info("updateM====" + JSONObject.toJSONString(updateM));
            merchantDao.updateById(updateM);
        }
    }

    @Override
    public void updateBalance(MerchantUpdateBalanceReq req) throws BusinessException {
        ValidateBusinessException.assertTrue(req.getBalance() > 0, ExceptionEnum.ERROR_2103);
        Integer deleteBalance = merchantDao.deleteBalance(req.getId(), req.getBalance());
        ValidateBusinessException.assertTrue(deleteBalance > 0, ExceptionEnum.ERROR_2102);
        OrderBalance param = new OrderBalance();
        param.setMerchantId(req.getId());
        param.setPayOrderId(null);
        param.setBalanceMoney(-req.getBalance());
        param.setRechargeType("deduction");
        if (StringUtils.isBlank(req.getNotes())) {
            param.setNotes("线下扣款");
        } else {
            param.setNotes(req.getNotes());
        }
        param.setNotes(req.getNotes());
        param.setStatus(SkuOrderStatusEnum.SUCCESS.getCode());
        param.setCreateTime(new Date());
        param.setPayTime(new Date());
        orderBalanceDao.insert(param);
    }

    @Override
    public void addBalance(MerchantUpdateBalanceReq req) throws BusinessException {
        ValidateBusinessException.assertTrue(req.getBalance() > 0, ExceptionEnum.ERROR_2103);
        Integer deleteBalance = merchantDao.addBalance(req.getId(), req.getBalance());
        ValidateBusinessException.assertTrue(deleteBalance > 0, ExceptionEnum.ERROR_2102);
        OrderBalance param = new OrderBalance();
        param.setMerchantId(req.getId());
        param.setPayOrderId(null);
        param.setBalanceMoney(req.getBalance());
        param.setRechargeType("add");
        if (StringUtils.isBlank(req.getNotes())) {
            param.setNotes("线下增款");
        } else {
            param.setNotes(req.getNotes());
        }
        param.setNotes(req.getNotes());
        param.setStatus(SkuOrderStatusEnum.SUCCESS.getCode());
        param.setCreateTime(new Date());
        param.setPayTime(new Date());
        orderBalanceDao.insert(param);
    }
}



